# Copyright [2011] [Ilya Rudakov]
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from ConfigParser import RawConfigParser
import signal

from subprocess import Popen
import threading, os
from django.core.exceptions import ObjectDoesNotExist
from job_manager.models import Feed
from job_manager.services.audit_service import audit
from job_manager.utils.logging_utils import getlogger

__author__ = 'irudakov'

LOG = getlogger(__name__)

def __open_job_process__(job_id, user):
    try:
        LOG.debug("Opening job process...")
    
        job, process = Feed.objects.get(id=job_id), None
        job.is_broken = False
        job.save()

        audit(job=job, user=user, action="S")

        try:
            os.putenv("JOBS_STORAGE_PATH", os.path.abspath("./jobs_storage"))
            process= Popen(["python", "%s/feed_runner.py" % job.path])
        except OSError:
            LOG.debug("Couldn't open process for feed id:%s" % job_id)
            LOG.debug("Setting 'feed is broken' state...")
            __set_job_is_broken__(job, user)
            return

        __update_job_pid__(job, process.pid)
        __create_pid_log_file__("%s/pid.app" % job.path, process.pid)

        if process.wait() != 0:
            __set_job_is_broken__(job, user)
    except ObjectDoesNotExist, ignore:
        LOG.debug("Job process start failed because job wasn't found. Job id: %s" % job_id)

def __update_job_pid__(job, pid):
    LOG.debug("Setting new pid:%s" % pid)
    job.pid = pid
    job.save()

def __set_job_is_broken__(job, user):
    job.is_broken = True
    job.save()

def __create_pid_log_file__(path, pid):
    pid_file = open(path, "w")
    pid_file.write(str(pid))
    pid_file.close()

def update_config_property(config_path, section, property, value):
    config = RawConfigParser()
    config.read(config_path)
    config.set(section, property, value)

    with open(config_path, "wb") as config_file:
        config.write(config_file)
        config_file.close()

def invoke_job_runner(job_id, user):
    LOG.debug("Preparing run job id:%s" % job_id)
    
    process_thread = threading.Thread(target=__open_job_process__, args=[job_id, user])
    process_thread.setDaemon(True)
    process_thread.start()
    del process_thread

def do_interrupt_job(job_id):
    try:
        job = Feed.objects.get(id=job_id)
        os.kill(job.pid, signal.SIGKILL)
    except ObjectDoesNotExist:
        LOG.debug("Somebody tried to interrupt job but job wasn't found. Job id: %s" % job_id)

